<script setup lang="ts">
import type { Socket } from 'socket.io-client'
import io from 'socket.io-client'
import { nextTick, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'

let socket: Socket
const router = useRouter()
const messages = ref('')
const msgList = ref<string[]>([])

onMounted(() => {
  socket = io('http://127.0.0.1:3007', {
    transports: ['websocket'],
  })

  // 接收消息事件
  socket.on('receiveMessage', async (msg) => {
    msgList.value.push(msg)
    await nextTick()
    window.scrollTo(0, document.body.scrollHeight)
  })

  // 与服务端连接成功
  socket.on('connect', () => {
    console.log('连接成功')
  })

  socket.on('reconnect_attempt', (attemptNumber) => {
    console.log(`重新连接尝试 #${attemptNumber}`)
  })

  socket.on('reconnect', (attemptNumber) => {
    console.log(`成功重新连接, 尝试次数: ${attemptNumber}`)
  })

  socket.on('reconnect_failed', () => {
    console.log('重新连接失败')
  })
})

// 发送消息事件
function sendMessage() {
  socket.emit('sendMessage', messages.value)
  messages.value = ''
}

function onClose() {
  socket.close()
  router.push('/')
}

function onDisconnect() {
  if (socket.connected) {
    socket.disconnect()
    console.log('断开连接')
  }
  else {
    socket.connect()
    socket.on('history', async (msgs) => {
      msgList.value = msgs
      await nextTick()
      window.scrollTo(0, document.body.scrollHeight)
    })
  }
}
</script>

<template>
  <ul id="messages">
    <li v-for="(item, index) in msgList" :key="index">
      {{ item }}
    </li>
  </ul>
  <div id="form">
    <input id="input" v-model="messages" autocomplete="off">
    <button @click="sendMessage">
      Send
    </button>
    <button @click="onClose">
      断开
    </button>
    <button @click="onDisconnect">
      Disconnect
    </button>
  </div>
</template>

<style scoped>
body {
  margin: 0;
  padding-bottom: 3rem;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
    Arial, sans-serif;
}

#form {
  background: rgba(0, 0, 0, 0.15);
  padding: 0.25rem;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  height: 3rem;
  box-sizing: border-box;
  backdrop-filter: blur(10px);
}
#input {
  border: none;
  padding: 0 1rem;
  flex-grow: 1;
  border-radius: 2rem;
  margin: 0.25rem;
}
#input:focus {
  outline: none;
}
#form > button {
  background: #333;
  border: none;
  padding: 0 1rem;
  margin: 0.25rem;
  border-radius: 3px;
  outline: none;
  color: #fff;
}

#messages {
  list-style-type: none;
  margin: 0;
  padding: 0;
}
#messages > li {
  padding: 0.5rem 1rem;
  height: 200px;
}
#messages > li:nth-child(odd) {
  background: #efefef;
}
</style>
